//
//  EditViewController.swift
//  Automobile
//
//  Created by erkebulan elzhan on 8/25/20.
//  Copyright © 2020 erkebulan elzhan. All rights reserved.
//

import UIKit


// TODO: Convert Options into needed format


final class EditViewController: UIViewController, Alertable {
    
    private lazy var tableView: UITableView = {
        let table = UITableView()
        table.delegate = self
        table.dataSource = self
        table.register(CarHeaderCell.self, forCellReuseIdentifier: "CarHeaderCell")
        table.register(EditDetailsCell.self, forCellReuseIdentifier: "EditDetailsCell")
        table.register(CarContactsCell.self, forCellReuseIdentifier: "CarContactsCell")
        table.register(EditActionsCell.self, forCellReuseIdentifier: "EditActionsCell")
        table.register(EditMainCell.self, forCellReuseIdentifier: "EditMainCell")
        table.showsVerticalScrollIndicator = false
        return table
    }()
    
    private lazy var modalView: ModalView = {
        let mView = ModalView(isMultiSelect: false)
        mView.delegate = self
        return mView
    }()
    
    private lazy var spinnerView = SpinnerView()
    
    // MARK: - Props
    
    public var post: Post!
    
    private var editViewModel: EditViewModel!
    private let placeholder = "Напишите что-нибудь"
    
    private var isLoading: Bool = false {
        didSet {
            view.isUserInteractionEnabled = !isLoading
            isLoading ? spinnerView.startAnimating() : spinnerView.stopAnimating()
        }
    }
    
    private var screenTap: UITapGestureRecognizer!
    
    // MARK: - Actions

    @objc private func onSubmitClick () {
        self.sendAdvert()
    }
    
    @objc private func onOpenOptions () {
        let optionsVC = OptionsViewController()
        optionsVC.callbackVC = self
        self.navigationController?.navigationBar.isHidden = false
        self.navigationController?.pushViewController(optionsVC, animated: true)
    }
    
    @objc private func closeVC () {
        self.goBack()
    }
    
    // MARK: - Init
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.addViews()
        self.editViewModel = EditViewModel(post: post)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        navigationController?.view.backgroundColor = UIColor.white
        setUpNav()
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        navigationController?.navigationBar.prefersLargeTitles = false
        navigationController?.navigationBar.isHidden = true
    }
    
    override func viewDidAppear(_ animated: Bool) {
        navigationController?.navigationBar.prefersLargeTitles = true
        NotificationCenter.default.addObserver(self, selector: #selector(getContactsCellUpdate(notification:)), name: NSNotification.Name(rawValue: "contactsUpdate"), object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(getModalUpdate(notification:)), name: NSNotification.Name(rawValue: "openEditModal"), object: nil)
        
        
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "openEditModal"), object: nil)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "contactsUpdate"), object: nil)
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
    }
    
    deinit {
        print("deiit")
    }
    
    // MARK: - Methods

    @objc private func getContactsCellUpdate (notification: NSNotification) {
        if let userInfo = notification.userInfo {
            if userInfo["isSelected"] as? Bool ?? false {
                self.openRegionVC()
            } else {
                self.selectCity(city: [])
            }
        }
    }
    
    @objc private func getModalUpdate (notification: NSNotification) {
        if let userInfo = notification.userInfo {
            let modal = userInfo["modal"] as! ModalView.ModalType
            let isCleared = userInfo["clear"] as? Bool
            if isCleared ?? false {
                
            } else {
                self.addModalView(modalType: modal)
            }
        }
    }
    
    @objc private func didTapToScreen () {
        if let cell = tableView.cellForRow(at: IndexPath(row: 2, section: 0)) {
            (cell as! EditDetailsCell).detailTextView.resignFirstResponder()
        }
    }
    
    @objc private func keyboardWillShow(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            self.tableView.transform = CGAffineTransform(translationX: 0, y: -keyboardSize.height + 54)
        }
    }

    @objc private func keyboardWillHide(notification: NSNotification) {
        self.tableView.transform = .identity
    }
    
    private func openRegionVC () {
        let regionsVC = RegionViewController()
        regionsVC.delegate = self
        self.navigationController?.pushViewController(regionsVC, animated: true)
    }
    
    @objc private func goBack () {
        if let VCs = navigationController?.viewControllers.count {
            let start = VCs == 0 ? 0 : VCs - 1
            var found = false
            for i in 0...start {
                if navigationController?.viewControllers[start-i] is AdsViewController {
                    (navigationController?.viewControllers[start-i] as! AdsViewController).doRefresh()
                    found = true
                    self.navigationController?.popToViewController((navigationController?.viewControllers[start-i])!, animated: true)
                }
             }
            
            if !found {
                self.navigationController?.popViewController(animated: true)
            }
        } else {
            self.navigationController?.popViewController(animated: true)
        }
    }
    
}

extension EditViewController: ModalViewDelegate, RegionViewControllerDelegate {
    
    func showError(_ title: String, _ message: String) {
        self.showAlert(title, message)
    }
    
    func selectCity(city: [City]) {
        self.post.city = city.item(at: 0)
        if let index = editViewModel.items.firstIndex(where: { $0 is CarContactsCellConfigurator }) {
            (editViewModel.items[index] as! CarContactsCellConfigurator).item?.city = city.item(at: 0)
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "setRegion"), object: nil, userInfo: ["region": city.item(at: 0) as Any])
        }
    }
    
    func onCancel() {
        //
    }
    
    func onSubmit(for type: ModalView.ModalType, data: Any) {
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "sendEditModal"), object: nil, userInfo: ["data": data, "type": type])
        modalView.removeFromSuperview()
        view.addGestureRecognizer(screenTap)
    }
}



// MARK: - Network

extension EditViewController {
    private func sendOptions (options: [String:Any]) {
        self.isLoading = true
        editViewModel.updateOptions(options: options, id: post.id) { (result) in
            self.isLoading = false
            switch result {
            case .failure(let err):
                self.alertError(error: err)
            case .success(_):
                self.showAlert("Успешно!", "Комплектации обновлены")
            }
        }
    }
    
    private func sendAdvert () {
        self.isLoading = true
        
        let desciptionCell = tableView.cellForRow(at: IndexPath(row: 2, section: 0)) as! EditDetailsCell
        let details = desciptionCell.detailTextView.text.trimmingCharacters(in: .whitespacesAndNewlines)
        
        let mainCell = tableView.cellForRow(at: IndexPath(row: 1, section: 0))
        let mainData = (mainCell as! EditMainCell).returnData()
        
        let contactsCell = tableView.cellForRow(at: IndexPath(row: 3, section: 0))
        let contactData = (contactsCell as! CarContactsCell).returnData()
        
        editViewModel.updateAdvert(id: post.id, city: post.city, contact_name: contactData?.name, contact_email: contactData?.email, description: details, mainData: mainData) { (result) in
            self.isLoading = false
            switch result {
            case .failure(let err):
                self.alertError(error: err)
            case .success(_):
                self.goBack()
            }
        }
    }
}



// MARK: - UI

extension EditViewController {
    
    private func addViews() {
        view.addSubview(tableView)
        view.addSubview(spinnerView)
        
        screenTap = UITapGestureRecognizer(target: self, action: #selector(didTapToScreen))
        view.addGestureRecognizer(screenTap)
        
        addConstraints()
    }
    
    private func addConstraints() {
        tableView.snp.makeConstraints { (make) in
            make.top.bottom.equalTo(view.safeAreaLayoutGuide)
            make.leading.trailing.equalToSuperview()
        }
        spinnerView.snp.makeConstraints { (make) in
            make.center.equalToSuperview()
        }
    }
    
    private func setUpNav () {
        self.addBackBtn()
        self.addCloseIcon()
        self.navigationItem.title = "Редактирование"
        self.navigationItem.largeTitleDisplayMode = .always
        self.navigationController?.navigationBar.isHidden = false
        self.navigationController?.navigationBar.backgroundColor = .whiteBlueColor
        self.navigationController?.navigationBar.defaultNavBar()
    }
    
    private func addCloseIcon () {
        let closeBarBnt = UIBarButtonItem(image: UIImage(named: "dismiss"), style: .plain, target: self, action: #selector(closeVC))
        closeBarBnt.tintColor = .greyColor
        self.navigationItem.rightBarButtonItem = closeBarBnt
    }
    
    private func addBackBtn () {
        let backButton = UIBarButtonItem(image: UIImage(named: "cancel"), style: .plain, target: self, action: #selector(goBack))
        backButton.tintColor = .greyColor
        backButton.tag = 0
        
        self.navigationItem.hidesBackButton = true
        self.navigationItem.leftBarButtonItem = backButton
    }

    private func addModalView (modalType: ModalView.ModalType) {
        self.view.addSubview(modalView)
        self.view.removeGestureRecognizer(screenTap)
        modalView.updateModalType(type: modalType)
        
        let height = modalType == .price ? 240 : 345
        
        modalView.snp.makeConstraints { (make) in
            make.leading.trailing.equalToSuperview()
            make.bottom.equalTo(view.safeAreaLayoutGuide)
            make.height.equalTo(height)
        }
    }
}


// MARK: - Table View

extension EditViewController: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return editViewModel.items.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let item = editViewModel.items[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: type(of: item).reuseId)!
        cell.selectionStyle = .none
        item.configure(cell: cell, index: indexPath.row)
        
        if cell is EditDetailsCell {
            (cell as! EditDetailsCell).detailTextView.delegate = self
            (cell as! EditDetailsCell).placeholder = placeholder
        }
        
        if cell is EditActionsCell {
            (cell as! EditActionsCell).readyBtn.addTarget(self, action: #selector(onSubmitClick), for: .touchUpInside)
            (cell as! EditActionsCell).optionsBtn.addTarget(self, action: #selector(onOpenOptions), for: .touchUpInside)
        }
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
}


extension EditViewController: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        self.tableView.beginUpdates()
        self.tableView.endUpdates()
    }
    func textViewDidBeginEditing(_ textView: UITextView) {
        if textView.text == placeholder {
            textView.text = ""
        }
    }

    
    func textViewDidEndEditing(_ textView: UITextView) {
        if textView.text == "" {
            textView.text = placeholder
        }
    }
}

extension EditViewController: OptionsViewControllerDelegate {
    func didSelectedOptions(options: [String : Any]?, filterFormat: [String]?) {
        self.sendOptions(options: options ?? [:])
    }
}
